import * as crypto from 'crypto';

const CRYPTO_ALGORITHM = 'aes-256-ctr';
const CRYPTO_IV_PREFIX = 'IV;';

const errorCode = {
  10001: '用户名或密码错误',
  10002: '用户名已存在',
  10003: '未找到该用户',
  10004: '未登录',
  10005: '用户权限不足',
  10006: '组名已存在',
  10007: '未找到用户组',
  10008: '该模块 uri 已存在',
  10009: '该模块不存在',
  10010: '该模块存在子模块，无法删除',

  20001: '请求参数错误',
  20002: '服务器错误',
  20003: '客户端权限不足',

  30000: '商品分类已存在',
  30010: '轮播图片名称已存在',

  30020: '商家名次已存在',
  
  40000: '支付订单不存在',
  50007: '未找到用户组',

  70000: '洗车客户已存在',
  70001: '洗车客户不存在'
};

const errorMsg = (code = 0): string =>
  code === 0 ? '' : errorCode[code] || errorCode[20002];

const encrypt = (text: string, secret: string): string => {
  const key = crypto
    .createHash('sha256')
    .update(secret)
    .digest();
  const iv = crypto.randomBytes(16);
  const cipher = crypto.createCipheriv(CRYPTO_ALGORITHM, key, iv);
  let crypted = cipher.update(text, 'utf8', 'hex');
  crypted += cipher.final('hex');
  return CRYPTO_IV_PREFIX + iv.toString('hex') + crypted;
};

const decrypt = (text: string, secret: string): string => {
  const key = crypto
    .createHash('sha256')
    .update(secret)
    .digest();
  const ivDataBuffer = Buffer.from(text.slice(CRYPTO_IV_PREFIX.length), 'hex');
  const iv = ivDataBuffer.slice(0, 16);
  const decipher = crypto.createDecipheriv(CRYPTO_ALGORITHM, key, iv);
  let dec = decipher.update(ivDataBuffer.slice(16), 'hex', 'utf8');
  dec += decipher.final('utf8');
  return dec;
};

const md5 = (text: string): string => {
  return crypto
    .createHash('md5')
    .update(text)
    .digest('hex');
};

function aesEncrypt(data: string, key: string) {
  const cipher = crypto.createCipher('aes192', key);
  let crypted = cipher.update(data, 'utf8', 'hex');
  crypted += cipher.final('hex');
  return crypted;
}

function aesDecrypt(encrypted: string, key: string) {
  const decipher = crypto.createDecipher('aes192', key);
  let decrypted = decipher.update(encrypted, 'hex', 'utf8');
  decrypted += decipher.final('utf8');
  return decrypted;
}


const encry = (algorithm: string, text: string): string => {
  return crypto
    .createHash(algorithm)
    .update(text)
    .digest('hex');
};

export default {
  errorMsg,
  errorCode,
  encrypt,
  decrypt,
  md5,
  encry,
  aesEncrypt,
  aesDecrypt,
};
